package net.ch2.pc12.tech.ackborn.dao;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Pattern;

import android.content.Context;

import net.ch2.pc12.tech.ackborn.R;
import net.ch2.pc12.tech.ackborn.model.BbsArticleModel;
import net.ch2.pc12.tech.ackborn.model.BbsBoardModel;
import net.ch2.pc12.tech.ackborn.model.BbsThreadModel;
import net.ch2.pc12.tech.ackborn.util.HttpUtils;
import net.ch2.pc12.tech.ackborn.util.SimpleHttpResponse;

public class SourceDAO {

	private static final String AGENT = "Monazilla/1.00 (AckBorn/0.1)";

	Context _context;
	
	public SourceDAO(Context context){
		super();
		_context = context;
	}
	
	private SourceDAO(){
		super();
	}
	
	/**
	 * BBSメニューから板の一覧を取得する
	 * @param 設定情報(BBSメニュー取得先等)
	 * @return 板の一覧
	 */
	public List<BbsBoardModel> getBbsBoardModelList() {
		
		// 板一覧
		List<BbsBoardModel> list = new ArrayList<BbsBoardModel>();
		
		String url = _context.getString(R.string.BbsUrl);
		
		HashMap<String,String> headers = new HashMap<String, String>();
		headers.put("User-Agent", AGENT);
		
		// URLにリクエスト投げる
		SimpleHttpResponse res = HttpUtils.sendSimpleRequest("GET", url, null,headers);
		String response = res.getResponseString();
		
		// レスポンスを解析する		
		StringReader reader = new StringReader(response);
		BufferedReader buf = new BufferedReader(reader);
		
		try {
						
			String line = "";
			
			int categoryPriority = 1;
			int boardPriority = 1;
			
			BbsBoardModel category = null;
			while((line=buf.readLine()) != null){
				// lineの中身を判定する
				// カテゴリだった
				if(isBbsCategory(line)){

					// カテゴリの値を行から取得する
					category = extractBbsCategory(line);
					
					// カテゴリの優先度をセット
					category.setGroupPriority(categoryPriority);
					
					// カテゴリの優先度を進める
					categoryPriority++;
					
					// 板の優先度を1にリセット
					boardPriority = 1;

				// 板だった
				}else if(isBbsBoard(line)){
					
					// カテゴリの下にないものは無視する
					// カテゴリの下であればこの値は空白ではないはず
					if(category != null){
						BbsBoardModel model = extractBbsBoard(line);
						
						// カテゴリの値から値を移す
						model.setGroupName(category.getGroupName());
						model.setGroupPriority(category.getGroupPriority());
						
						// 板の優先度をセット
						model.setBoardPriority(boardPriority);
						
						// 板の優先度を進める
						boardPriority++;
						
						list.add(model);
					}

				// その他だった
				}else{
					// 無視する
				}								
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			try {
				buf.close();
				reader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		// listを返す
		return list;
	}
	
	private boolean isBbsCategory(String line){
		
		boolean ret = false;
		
		// 例：<BR><BR><B>地震</B><BR>
		
		// <BR><BR><B>から始まる
		ret = Pattern.matches("<BR><BR><B>.*", line);
		
		return ret;
		
	}
	
	private boolean isBbsBoard(String line){

		 boolean ret = false;
		
		// 例：<A HREF=http://live24.2ch.net/eq/>臨時地震</A><br>

		// A HREF=から始まる		
		// http://*/idname/
		// 形式であればOK
		// (/の数は4つ)
		// href=が/で終わってないものは対象外
		// target=が行に含まれていない 
		ret = Pattern.matches("<A HREF=http://.*/.*/>.*</A>.*", line);

		return ret;
	}
	
	private BbsBoardModel extractBbsCategory(String line){
		BbsBoardModel model = new BbsBoardModel();
		
		// lineを解析して、値を抽出する
		// カテゴリ名を抽出

		// ヘッドを取り除く
		line = line.substring("<BR><BR><B>".length());
		
		// フッタを取り除く
		line = line.substring(0,line.indexOf("</B>"));

		model.setGroupName(line);
		
		return model;
		
	}
	
	private BbsBoardModel extractBbsBoard(String line){
		BbsBoardModel model = new BbsBoardModel();

		// 例：<A HREF=http://live24.2ch.net/eq/>臨時地震</A><br>
		
		// URLを抽出
		String url = line.substring("<A HREF=".length());
		url = url.substring(0,url.indexOf(">"));
		model.setBoardUrl(url);

		// IDを抽出
		String bbsId = url.substring(0,url.lastIndexOf("/"));
		bbsId = bbsId.substring(bbsId.lastIndexOf("/")+1);
		model.setBoardId(bbsId);
		
		// 板名を抽出
		String name = line.substring(line.indexOf(">")+1);
		name = name.substring(0,name.indexOf("</A>"));
		model.setBoardName(name);
		
		return model;
	}

	public List<BbsThreadModel> getBbsThreadModelList(
			BbsBoardModel bbsBoardModel) {

		ArrayList<BbsThreadModel> list = new ArrayList<BbsThreadModel>();
		
		HashMap<String,String> headers = new HashMap<String,String>();
		headers.put("User-Agent", AGENT);
		headers.put("Referer", "");

		String url = getServerUrl("GET",bbsBoardModel.getBoardUrl(),null,headers);
		if(url == null || url.equals("")){
			// 404
			return null;
		}

		url+="subject.txt";
		
		// URLにリクエスト投げる
		SimpleHttpResponse res = HttpUtils.sendSimpleRequest("GET", url, null,headers);
		String response = res.getResponseString();
		// レスポンスを解析する		
		StringReader reader = new StringReader(response);
		BufferedReader buf = new BufferedReader(reader);
		String line;
		try {
			int cnt = 1;
			while((line = buf.readLine()) != null){
				list.add(extractBbsThread(line, bbsBoardModel.getBoardId(), cnt));
				cnt++;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				buf.close();
				reader.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		return list;
	}
	
	private BbsThreadModel extractBbsThread(String line,String boardId,int priority){
		BbsThreadModel model = new BbsThreadModel();

		String dat = line.substring(0,line.indexOf("<>"));
		String tid = dat.substring(0,dat.indexOf(".dat"));
		String tname = line.substring(line.indexOf("<>")+"<>".length(),line.lastIndexOf("("));
		String cnt = line.substring(line.lastIndexOf("(") + "(".length(),line.lastIndexOf(")"));

		model.setBoardId(boardId);
		model.setCount(Integer.parseInt(cnt));
		model.setDatName(dat);
		model.setPriority(priority);
		model.setThreadId(tid);
		model.setThreadName(tname);
		
		return model;
	}
	
	private String getServerUrl(String method,String url,Map<String,String> param,Map<String,String> headers){
		// URLにリクエスト投げる
		SimpleHttpResponse res = HttpUtils.sendSimpleRequest("GET", url, null,headers);
		String response = res.getResponseString();
		String ret = null;

		if(res.getResponseCode() == 404){
			return ret;
		}
		
		
		int in = response.indexOf("<title>2chbbs..</title>");
		if(in != -1){

			// 移転してる

			// レスポンスを解析する
			StringReader reader = new StringReader(response);
			BufferedReader buf = new BufferedReader(reader);			
			String line;
			try {
				while((line = buf.readLine()) != null){
					line = getJumpUrl(line);
					if(line != null){
						ret = getServerUrl(method, line, param, headers);
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally{
				try {
					buf.close();
					reader.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}

		}else{
			// 移転してない、これがあたり
			ret = url;
		}
		
		return ret;
	}

	private String getJumpUrl(String line){
		String ret = null;
		boolean contain = Pattern.matches(".*window.location.href=.*", line);
		if(contain){
			line = line.substring(line.indexOf("=\"")+"=\"".length());
			line = line.substring(0,line.indexOf("\"</"));
			ret = line;
		}
		return ret;
	}

	public List<BbsArticleModel> getArticleModelList(
			BbsThreadModel bbsThreadModel) {

		ArrayList<BbsArticleModel> list = new ArrayList<BbsArticleModel>();
		
		HashMap<String,String> headers = new HashMap<String,String>();
		headers.put("User-Agent", AGENT);
		headers.put("Referer", "");

		String url = getServerUrl("GET",bbsThreadModel.getBoardUrl(),null,headers);
		if(url == null || url.equals("")){
			// 404
			return null;
		}

		url+="/dat/" + bbsThreadModel.getDatName();
		
		// URLにリクエスト投げる
		SimpleHttpResponse res = HttpUtils.sendSimpleRequest("GET", url, null,headers);
		String response = res.getResponseString();
		// レスポンスを解析する		
		StringReader reader = new StringReader(response);
		BufferedReader buf = new BufferedReader(reader);
		String line;
		try {
			int cnt = 1;
			while((line = buf.readLine()) != null){
				list.add(extractBbsArticle(line,cnt));
				cnt++;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				buf.close();
				reader.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		return list;
	}
	
	private BbsArticleModel extractBbsArticle(String line,int cnt){
		BbsArticleModel model = new BbsArticleModel();
		
		StringTokenizer st = new StringTokenizer(line,"<>");
		String[] nodes = line.split("<>");
		String name = nodes[0];
		String mail = nodes[1];
		String dates = nodes[2];
		String id;
		String date;
		String be;
		if(dates.indexOf("ID:") != -1){
			date = dates.substring(0,dates.indexOf("ID:"));
			id = dates.substring(dates.indexOf("ID:") + "ID:".length());
			if(id.indexOf("BE:") != -1){
				be = id.substring(id.indexOf("BE:") + "BE:".length());
				id = id.substring(0,id.indexOf("BE:"));
			}else{
				be = "";
			}
		}else{
			date = dates;
			id = "";
			be = "";
		}
		String contents="";
		for(int i=3;i<nodes.length;i++){
			contents += nodes[i].replace("<br>", "\n");
		}

		model.setDate(date);
		model.setId(id);
		model.setMail(mail);
		model.setContents(contents);
		model.setName(name);
		model.setNum(Integer.toString(cnt));
		model.setBe(be);
		
		return model;
	}
	
}
